#
from typing import Dict
import cupynumeric as np
import cupy as cp
from cupyx.scipy import linalg as CSL #import lu

'''
准备环境：
pip install cupy

conda create -n zywy -c conda-forge -c legate cupynumeric
conda activate zywy
# 指定可以独占使用的GPU
export CUDA_VISIBLE_DEVICES=1,2
'''
class CunpApp(object):
    def __init__(self):
        self.name = 'apps.mar.cunp_app.CunpApp'

    @staticmethod
    def startup(params:Dict = {}) -> None:
        print('CUDA版Numpy试验程序')
        # CunpApp.solve_tme()
        # CunpApp.qr_decomposition()
        # CunpApp.lu_decomposition()
        # CunpApp.cholesky_decomposition()
        CunpApp.matrix_inverse()

    @staticmethod
    def solve_tme() -> None:
        '''
        求解三角矩阵方程
        '''
        # 定义一个下三角矩阵
        L = np.array([[1, 0, 0],
                    [2, 3, 0],
                    [4, 5, 6]])

        # 定义一个向量
        b = np.array([1, 2, 3])

        # 求解下三角矩阵方程 Lx = b
        x = np.linalg.solve(L, b)

        print("解向量 x:", x)

    @staticmethod
    def qr_decomposition() -> None:
        print(f'QR分解示例')
        # 定义一个矩阵A
        A = np.array([[12, -51, 4],
                    [6, 167, -68],
                    [-4, 24, -41]], dtype=np.float64)
        # 使用CuPy的linalg模块进行QR分解
        Q, R = np.linalg.qr(A)
        # 输出结果
        print("正交矩阵 Q:\n", Q)
        print("上三角矩阵 R:\n", R)
        # 验证QR分解的正确性
        print("验证: Q @ R\n", Q @ R)
        # 假设你是cupy技术专家，请提供LU分解例程


    @staticmethod
    def lu_decomposition() -> None:
        # 创建一个2x2的矩阵
        A = cp.array([[3, 1], [1, 2]], dtype=np.float64)
        # 执行LU分解
        P, L, U = CSL.lu(A)
        # 打印结果
        print("原始矩阵 A:")
        print(A)
        print("置换矩阵 P:")
        print(P)
        print("下三角矩阵 L:")
        print(L)
        print("上三角矩阵 U:")
        print(U)

    @staticmethod
    def cholesky_decomposition() -> None:
        print(f'cholesky_decomposition示例')
        A = np.array([[4, 1], [1, 3]], dtype=np.float32)
        L = np.linalg.cholesky(A)
        print(f'L: {L};')

    @staticmethod
    def matrix_inverse() -> None:
        # print(f'矩阵求逆示例')
        # A = np.array([[4, 1], [2, 3]], dtype=np.float32)
        # A_inv = np.linalg.inv(A)
        # print(f'A_inv: {A_inv};')
        # # 请提供cupy库求矩阵逆的例程
        # 创建一个2x2的矩阵
        A = cp.array([[1, 2], [3, 4]], dtype=np.float64)
        # 使用CuPy的linalg.inv函数计算矩阵的逆
        A_inv = cp.linalg.inv(A)
        # 打印结果
        print("矩阵A的逆矩阵A_inv:")
        print(A_inv)